package cn.fzc.example.redis.distributedlock.manager;

import cn.fzc.example.redis.distributedlock.DistributeLock;
import cn.fzc.example.redis.distributedlock.ILock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;

/**
 * @Author: fu.zc
 * @Date: 2020/8/5 13:56
 * @Description:
 */
@Component
public class SimpleRedisLockManager implements ILockManager {

    @Autowired
    protected StringRedisTemplate redisTemplate;

    protected ILock distributeLock;

    @PostConstruct
    public void init() {
        distributeLock = new DistributeLock(redisTemplate);
    }



    @Override
    public void lockCallBack(String lockKeyName, SimpleCallBack callback) {

        Assert.notNull("lockKeyName","lockKeyName 不能为空");
        Assert.notNull("callback","callback 不能为空");

        try {
            distributeLock.lock(lockKeyName);
            callback.execute();
        }finally {
            distributeLock.unlock(lockKeyName);
        }

    }

    @Override
    public <T> T lockCallBackWithRtn(String lockKeyName, ReturnCallBack<T> callback) {
        Assert.notNull("lockKeyName","lockKeyName 不能为空");
        Assert.notNull("callback","callback 不能为空");
        try{
            // 获取锁
            distributeLock.lock(lockKeyName);
            return callback.execute();
        }finally{
            // 必须释放锁
            distributeLock.unlock(lockKeyName);
        }
    }
}
